#define DEBUG
using System.Diagnostics;

namespace ICSharpCode.TextEditor.Document
{
	public class DefaultSelection : ISelection
	{
		private IDocument document;

		private bool isRectangularSelection;

		private TextLocation startPosition;

		private TextLocation endPosition;

		public TextLocation StartPosition
		{
			get
			{
				return this.startPosition;
			}
			set
			{
				DefaultDocument.ValidatePosition(this.document, value);
				this.startPosition = value;
			}
		}

		public TextLocation EndPosition
		{
			get
			{
				return this.endPosition;
			}
			set
			{
				DefaultDocument.ValidatePosition(this.document, value);
				this.endPosition = value;
			}
		}

		public int Offset => this.document.PositionToOffset(this.startPosition);

		public int EndOffset => this.document.PositionToOffset(this.endPosition);

		public int Length => this.EndOffset - this.Offset;

		public bool IsEmpty => this.startPosition == this.endPosition;

		public bool IsRectangularSelection
		{
			get
			{
				return this.isRectangularSelection;
			}
			set
			{
				this.isRectangularSelection = value;
			}
		}

		public string SelectedText
		{
			get
			{
				if (this.document != null)
				{
					if (this.Length < 0)
					{
						return null;
					}
					return this.document.GetText(this.Offset, this.Length);
				}
				return null;
			}
		}

		public DefaultSelection(IDocument document, TextLocation startPosition, TextLocation endPosition)
		{
			DefaultDocument.ValidatePosition(document, startPosition);
			DefaultDocument.ValidatePosition(document, endPosition);
			Debug.Assert(startPosition <= endPosition);
			this.document = document;
			this.startPosition = startPosition;
			this.endPosition = endPosition;
		}

		public override string ToString()
		{
			return $"[DefaultSelection : StartPosition={this.startPosition}, EndPosition={this.endPosition}]";
		}

		public bool ContainsPosition(TextLocation position)
		{
			if (this.IsEmpty)
			{
				return false;
			}
			return (this.startPosition.Y < position.Y && position.Y < this.endPosition.Y) || (this.startPosition.Y == position.Y && this.startPosition.X <= position.X && (this.startPosition.Y != this.endPosition.Y || position.X <= this.endPosition.X)) || (this.endPosition.Y == position.Y && this.startPosition.Y != this.endPosition.Y && position.X <= this.endPosition.X);
		}

		public bool ContainsOffset(int offset)
		{
			return this.Offset <= offset && offset <= this.EndOffset;
		}
	}
}
